Exploratory Data Analysis (EDA) merupakan serangkaian langkah untuk mengenal lebih jauh data yang anda miliki, istilah Eksplor digunakan untuk mencoba menjelajahi bagaimana bentuk data, hubungan hubungan yang ada pada data, ataupun hanya sekedar ingin tahu bagaimana nilai nilai yang ada pada data yang kita miliki.
EDA sangat penting sebelum kita langsung terjun ke membuat model ataupun analisa kompleks lainnya, EDA bekerja sebagai fondasi awal untuk mengetahui apa aja sih yang bisa kita kerjakan dari data yang kita miliki, hipotesa hipotesa apa saja yang bisa di eksplor dari data yang kita punya. Seringkali dengan melakukan eksplorasi data, banyak sekali insight yang bisa didapat.
Yang dimaksud dengan sudah benar adalah apakah setiap variabel tidak memiliki nilai yang ‘aneh’
Jika didapatkan nilai yang aneh, bagaimana seharusnya kita menghandle nilai tersebut?
Memastikan tipe data apakah sudah sesuai apa belum merupakan step krusial pertama, dikarenakan tipe data yang berbeda akan diperlakukan berbeda pula di R, walaupun isinya tetap sama.
Tipe-tipe data yang umum dalam R adalah:
Mengetahui tipe tipe data ini sangat penting dalam sebelum memulai analisis, pastikan tipe data dari masing masing variabel sudah tepat, berikut definisi dan contoh dari tipe data tersebut:
Berikut disajikan data
Untuk melihat apakah tipe datanya sudah benar, dapat menggunakan
## Kota AQI Tingkat Polusi Temperatur Cuaca
## "character" "numeric" "character" "numeric" "character"
ataupun
## Classes 'tbl_df', 'tbl' and 'data.frame': 34 obs. of 5 variables:
## $ Kota : chr "Depok" "Batam" "Jakarta" "Medan" ...
## $ AQI : num 180 157 164 127 172 234 199 134 278 401 ...
## $ Tingkat Polusi: chr "Unhealthy" "Unhealthy" "Unhealthy" "Unhealthy for Sensitive Groups" ...
## $ Temperatur : num 25 27 25 24 25 23 23 25 23 23 ...
## $ Cuaca : chr "Mist" "Mist" "Mist" "Mist" ...
Apakah tipe datanya sudah benar? jika belum, dapat diganti menggunakan
aqi$`Tingkat Polusi`<-factor(aqi$`Tingkat Polusi`,levels=c('Good','Moderate','Unhealthy for Sensitive Groups','Unhealthy','Very Unhealthy','Hazardous'), ordered = TRUE)
aqi$Cuaca<-factor(aqi$Cuaca, ordered = FALSE)## Classes 'tbl_df', 'tbl' and 'data.frame': 34 obs. of 5 variables:
## $ Kota : chr "Depok" "Batam" "Jakarta" "Medan" ...
## $ AQI : num 180 157 164 127 172 234 199 134 278 401 ...
## $ Tingkat Polusi: Ord.factor w/ 6 levels "Good"<"Moderate"<..: 4 4 4 3 4 5 4 3 5 6 ...
## $ Temperatur : num 25 27 25 24 25 23 23 25 23 23 ...
## $ Cuaca : Factor w/ 5 levels "Broken Clouds",..: 4 4 4 4 4 1 1 1 1 1 ...
## [1] FALSE
## [1] TRUE
Missing Value dalah nilai yang hilang dari data
Mengapa terjadi missing value dapat disebabkan oleh berbagai macam hal:
Ataupun contoh lainnya pada data survey * Responden lupa mengisi pertanyaan * Responden mengosongkan pertanyaan karena pernyataan sulit dimengerti * Responden enggan untuk mengisi pertanyaan yang sensitif
Biasanya untuk menandakan bahwa suatu data hilang, cell tersebut dibiarkan kosong Nah, permasalahan yang dihadapi pada data di lapangan adalah, penandaan untuk mengatakan bahwa data tersebut missing sangat beragam, bisa ditulis ‘?’ (tanda tanya), bisa ditulis ‘-‘ (strip), bisa suatu bilangan yang sangat besar atau sangat kecil (misal 99 atau -999)
house<-read.csv("https://raw.githubusercontent.com/dataoptimal/posts/master/data%20cleaning%20with%20python%20and%20pandas/property%20data.csv")
housediabetes<-read.csv('https://raw.githubusercontent.com/DevSurya/Pima-Diabetes-Prediction/master/data/pima-data.csv')
sample_n(diabetes,10)## num_preg glucose_conc diastolic_bp thickness
## Min. : 0.000 Min. : 0.0 Min. : 0.00 Min. : 0.00
## 1st Qu.: 1.000 1st Qu.: 99.0 1st Qu.: 62.00 1st Qu.: 0.00
## Median : 3.000 Median :117.0 Median : 72.00 Median :23.00
## Mean : 3.845 Mean :120.9 Mean : 69.11 Mean :20.54
## 3rd Qu.: 6.000 3rd Qu.:140.2 3rd Qu.: 80.00 3rd Qu.:32.00
## Max. :17.000 Max. :199.0 Max. :122.00 Max. :99.00
## insulin bmi diab_pred age
## Min. : 0.0 Min. : 0.00 Min. :0.0780 Min. :21.00
## 1st Qu.: 0.0 1st Qu.:27.30 1st Qu.:0.2437 1st Qu.:24.00
## Median : 30.5 Median :32.00 Median :0.3725 Median :29.00
## Mean : 79.8 Mean :31.99 Mean :0.4719 Mean :33.24
## 3rd Qu.:127.2 3rd Qu.:36.60 3rd Qu.:0.6262 3rd Qu.:41.00
## Max. :846.0 Max. :67.10 Max. :2.4200 Max. :81.00
## skin diabetes
## Min. :0.0000 Mode :logical
## 1st Qu.:0.0000 FALSE:500
## Median :0.9062 TRUE :268
## Mean :0.8091
## 3rd Qu.:1.2608
## Max. :3.9006
Manusia cenderung belajar dengan mudah dengan visual, bagaimana membuat visualisasi yang baik dan pewarnaan yang sesuai dapat mengungkap pola tersembunyi dan insight tambahan dalam EDA
Visualisasi Interaktif dapat dengan mudah diterapkan di R, setelah membuat objek ggplot, kita hanya tinggal melakukan ggplotly(objek-ggplot)
## [1] 1704 6
## country continent year lifeExp
## Afghanistan: 12 Africa :624 Min. :1952 Min. :23.60
## Albania : 12 Americas:300 1st Qu.:1966 1st Qu.:48.20
## Algeria : 12 Asia :396 Median :1980 Median :60.71
## Angola : 12 Europe :360 Mean :1980 Mean :59.47
## Argentina : 12 Oceania : 24 3rd Qu.:1993 3rd Qu.:70.85
## Australia : 12 Max. :2007 Max. :82.60
## (Other) :1632
## pop gdpPercap
## Min. : 60011 Min. : 241.2
## 1st Qu.: 2793664 1st Qu.: 1202.1
## Median : 7023596 Median : 3531.8
## Mean : 29601212 Mean : 7215.3
## 3rd Qu.: 19585222 3rd Qu.: 9325.5
## Max. :1318683096 Max. :113523.1
##
Barchart digunakan utamanya sebagai komparasi antara banyaknya jumlah/count pada variabel variabel kategorik pada Data
Misalkan kita mau melihat banyaknya negara pada tiap benua
Agar visualisasi lebih menarik, alangkah baiknya diberikan warna yang berbeda untuk tiap benua agar tidak monoton
ggplot(gapminder_2007,
aes(x = continent,
fill = continent)) +
geom_bar()+
theme(legend.position="none")Barchart ini juga dapat dibuat versi horizontalnya
ggplot(gapminder_2007,
aes(x=continent,
fill=continent)) +
geom_bar() +
coord_flip() +
theme(legend.position = "none")Stacked Bar Chart digunakan untuk melihat bagaimana komposisi komposisi pada suatu variabel kategorik di beberapa nilai yang berbeda.
Misalnya kita ingin melihat banyaknya negara di tiap benua, namun dibedakan berdasarkan apakah negara tersebut mempunyai harapan hidup yang lebih dari 50 tahun apa tidak.
Berikut kondisi negara negara tersebut pada tahun 1952
Berikut pada tahun 2007
Jika fokus utamanya adalah berapa persen di tiap benua yang berada di bawah 50 tahun harapan hidupnya, dapat digunakan versi stacked bar chart yang fokus pada persentase
Histogram digunakan untuk melihat distribusi yang ada pada suatu data numerik
Misalnya kita ingin melihat persebaran nilai harapan hidup pada seluruh negara pada tahun 1952
Dan pada tahun 2007
Kita juga dapat membandingkan 2 histogram sekaligus dalam satu frame
Jika ingin lebih fokus kepada bagaimana persebaran per kontinen nya, dapat juga menggambar histogram per kontinen
Plot selanjutnya adalah Boxplot, Boxplot berfokus pada bagaimana jangkauan data
g<-ggplot(gapminder_2007,
aes(y = lifeExp,
x = continent,
fill = continent)) +
geom_boxplot()
ggplotly(g)Versi horizontalnya
Violinplot dapat mempermudah kita melihat persebaran di beberapa kategori
Violinplot dan boxplot dapat digabungkan menjadi satu visualisasi yang ringkas
ggplot(gapminder_2007,
aes(y = lifeExp,
x = continent,
fill = continent)) +
geom_violin() +
geom_boxplot(width=0.1)Line chart utamanya digunakan untuk melihat progress over time
Misal kita ingin melihat bagaimana perkembangan beberapa negara di ASEAN, misal Indonesia, Singapore, Malaysia, dan Thailang
Lalu kita mau lihat bagaimana perkembangan gdp pertahunnya
ataupun perkembangan harapan hidup
maupun perkembangan populasi
Kita juga dapat merangkum yang lebih jauh, misalnya melihat perkembangan per benua, nah bagaimana merangkum nilai nilai yang ada pada benua? diperlukan suatu nilai yang cukup representatif menggambarkan keadaan benua tersebut, perhatikan demonstrasi berikut
ggplot(gapminder_2007,
aes(x = gdpPercap)) +
geom_histogram() +
geom_vline(xintercept = mean(gapminder_1952$gdpPercap),colour="red")+
geom_vline(xintercept = median(gapminder_1952$gdpPercap), colour="blue")Pada distribusi distribusi yang skewed, nilai mean akan sensitif terhadap kehadiran outlier.
Misalnya jika diberikan data {2,3,4,3,4,7,2,3,3,100} akan memiliki rata rata sekitar 13, sebuah nilai yang kurang merepresentasikan data, karena mayoritas berada pada nilai satuan yang kecil.
Mari kita coba rangkum bagaimana mean dan median tiap variabel pertahunnya berdasarkan benua
gapminder_per_continent<-gapminder %>% dplyr::group_by(year,continent) %>% dplyr::summarise(median_gdp = median(gdpPercap),
mean_gdp = mean(gdpPercap),
median_lifeExp = median(lifeExp),
mean_lifeExp = mean(lifeExp),
median_pop = median(pop),
mean_pop = mean(pop))
gapminder_per_continentDapat dilihat bahwa mean dan median sangat berbeda jauh nilainya, dikarenakan memang data yang didapat cukup right-skewed
Berikut bagaimana perkembangan per 5 tahun median gdp setiap benua
g<-ggplot(gapminder_per_continent,
aes(x = year,
y = median_gdp,
color = continent)) +
geom_line()
ggplotly(g)Berikut perkembangan untuk populasi
g<-ggplot(gapminder_per_continent,
aes(x = year,
y = median_pop,
color = continent)) +
geom_line()
ggplotly(g)Berikut perkembangan untuk ekspektasi hidup
Kekuatan scatterplot berada pada melihat bagaimana hubungan antar dua variabel. Misal kita ingin melihat bagaimana hubungan antara gdp dengan ekspektasi hidup, apakah semakin besar pendapatan suatu negara, maka semakin besar harapan hidup penduduknya?
ggplot(gapminder_2007,
aes(x=gdpPercap,
y=lifeExp)) +
geom_point() +
labs(subtitle="gdpPercap Vs lifeExp",
x="gdpPercap",
y="lifeExp",
title="Scatterplot",
caption = "Source: gapminder")Untuk melihat pola yang lebih jauh, mungkin akan lebih baik jika skala x nya diubah, menjadi skala logaritmik
ggplot(gapminder_2007,
aes(x=gdpPercap,
y=lifeExp)) +
geom_point() +
labs(subtitle="gdpPercap Vs lifeExp",
x="gdpPercap",
y="lifeExp",
title="Scatterplot, Scale x log10",
caption = "Source: gapminder") +
scale_x_log10()Selain menunjukkan hubungan 2 variabel, scatterplot dapat ditambahkan variabel ketiga, yaitu pewarnaan berdasarkan variabel tertentu, misalnya kita mau membedakan berdasarkan benua
ggplot(gapminder_2007,
aes(x=gdpPercap,
y=lifeExp)) +
geom_point(aes(col=continent)) +
labs(subtitle="gdpPercap Vs lifeExp",
x="gdpPercap",
y="lifeExp",
title="Scatterplot, Scale x log 10, colored by continent",
caption = "Source: gapminder") +
scale_x_log10()Bubbpleplot adalah scatterplot dengan besar titik yang beragam, besarnya titik tersebut dapat diatur dengan variabel lainnya, yang secara tidak langsung kita menambahkan variabel ke empat pada gambar, misalnya kita mau membedakan besarnya titik berdasarkan populasi
ggplot(gapminder_2007,
aes(x=gdpPercap,
y=lifeExp)) +
geom_point(aes(col=continent,
size=pop)) +
labs(subtitle="gdpPercap Vs lifeExp",
x="gdpPercap",
y="lifeExp",
title="Bubbleplot, Scale x log 10, colored by continent",
caption = "Source: gapminder") +
scale_x_log10()Nah, visualisasi interaktif sangat membantu kita dalam mengeksplor lebih jauh dari presentasi yang kita buat
g<-ggplot(gapminder_2007,
aes(x=gdpPercap,
y=lifeExp,
label=country)) +
geom_point(aes(col=continent,
size=pop)) +
labs(subtitle="gdpPercap Vs lifeExp",
x="gdpPercap",
y="lifeExp",
title="Bubbleplot, Scale x log 10, colored by continent",
caption = "Source: gapminder") +
scale_x_log10()
ggplotly(g)Kita dapat juga menggambarkan garis regresi linear pada data
g<-ggplot(gapminder_2007,
aes(x=gdpPercap,
y=lifeExp,
label=country)) +
geom_point(aes(col=continent,
size=pop)) +
geom_smooth(method="lm",
formula = "y~log(x)")
labs(subtitle="gdpPercap Vs lifeExp",
x="gdpPercap",
y="lifeExp",
title="Bubbleplot , Scale x log 10, colored by continent",
caption = "Source: gapminder") +
scale_x_log10()## NULL
g<-ggplot(gapminder_2007,
aes(x=gdpPercap,
y=lifeExp,
label=country)) +
geom_point(aes(col=continent,
size=pop)) +
geom_smooth(aes(col=continent),
method="lm",
formula = "y~log(x)",
se=F,
fullrange=T)
labs(subtitle="gdpPercap Vs lifeExp",
x="gdpPercap",
y="lifeExp",
title="Bubbleplot, Scale x log 10, colored by continent",
caption = "Source: gapminder") +
scale_x_log10()## NULL
g<-ggplot(gapminder,
aes(x=gdpPercap,
y=lifeExp,
label=country,
frame=year)) +
geom_point(aes(col=continent,
size=pop)) +
labs(subtitle="gdpPercap Vs lifeExp",
x="gdpPercap",
y="lifeExp",
title="Bubbleplot over the year",
caption = "Source: gapminder") +
scale_x_log10()
ggplotly(g)g<-ggplot(gapminder,
aes(x=gdpPercap,
y=lifeExp,
label=country,
frame=year)) +
geom_point(aes(col=continent,
size=pop)) +
geom_smooth(aes(col=continent),
method="lm",
formula = "y~log(x)",
se=F) +
labs(subtitle="gdpPercap Vs lifeExp",
x="gdpPercap",
y="lifeExp",
title="Bubbleplot over the year with regression line",
caption = "Source: gapminder") +
scale_x_log10()
ggplotly(g)gapminder_asia_2007 <- gapminder %>% filter(year==2007 & continent == "Asia")
gapminder_asia_2007$gdp_z <- round((gapminder_asia_2007$gdpPercap - mean(gapminder_asia_2007$gdpPercap))/sd(gapminder_asia_2007$gdpPercap), 2) # compute normalized gdpPercap
gapminder_asia_2007$gdp_type <- ifelse(gapminder_asia_2007$gdp_z < 0, "below", "above") # above / below avg flag
gapminder_asia_2007 <- gapminder_asia_2007[order(gapminder_asia_2007$gdp_z), ] # sort
gapminder_asia_2007$country <- factor(gapminder_asia_2007$country, levels = gapminder_asia_2007$country) # convert to factor to retain sorted order in plot.
# Diverging Barcharts
g<-ggplot(gapminder_asia_2007, aes(x=country, y=gdp_z, label=gdpPercap)) +
geom_bar(stat='identity', aes(fill=gdp_type), width=.5) +
scale_fill_manual(name="Mileage",
labels = c("Above Average", "Below Average"),
values = c("above"="#00ba38", "below"="#f8766d")) +
labs(subtitle="Normalised gdp from 'gapminder'",
title= "Diverging Bars") +
coord_flip()
ggplotly(g)gapminder_lifeExp_asia_before_after <- gapminder %>% filter(continent == "Asia" & year %in% c(1952,2007)) %>% select(-c(continent,pop,gdpPercap,lifeExpCat))
gapminder_lifeExp_asia_before_after <- spread(gapminder_lifeExp_asia_before_after, key = year, value = lifeExp)
colnames(gapminder_lifeExp_asia_before_after) <- c("country","year_1952","year_2007")
gapminder_lifeExp_asia_before_after <- gapminder_lifeExp_asia_before_after[order(gapminder_lifeExp_asia_before_after$year_1952), ] # sort
gapminder_lifeExp_asia_before_after$country <- factor(gapminder_lifeExp_asia_before_after$country, levels = gapminder_lifeExp_asia_before_after$country) # convert to factor to
gapminder_lifeExp_asia_before_after$diff <- gapminder_lifeExp_asia_before_after$year_2007 - gapminder_lifeExp_asia_before_after$year_1952
dumbbell_lifeExp_Asia <- plot_ly(gapminder_lifeExp_asia_before_after, color = I("gray80"),
hoverinfo = 'text') %>%
add_segments(x = ~year_2007, xend = ~year_1952, y = ~country, yend = ~country, showlegend = FALSE) %>%
add_markers(x = ~year_2007, y = ~country, name = "Life Exp year 2007",color='red', text=~paste('Life Exp year 2007: ', year_2007)) %>%
add_markers(x = ~year_1952, y = ~country, name = "Life Exp year 1952",color='blue', text=~paste('Life Exp year 1952: ', year_1952))%>%
layout(
title = "Life Exp Before After",
xaxis = list(title = "Life Exp"),
yaxis= list(title=""))
ggplotly(dumbbell_lifeExp_Asia)